home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 431_01 / rserver.c < prev    next >
Text File  |  1995-01-06  |  23KB  |  931 lines

  1. /*
  2.   SERVER
  3.     1. wait for request packets
  4.     2. execute request packet
  5.     3. package result
  6.     4. continue
  7.  
  8.   notes:
  9.      each function is in C but calls DOS through intr().
  10.      this is clunky, i know, but it comes from a bizarre design. initially
  11.      i thought i could translate everything into C calls (open, close, etc..)
  12.      but no such luck because i had to translate the C return codes to DOS
  13.      codes which was much too much trouble. later, it turns out the that
  14.      _doserrno holds the DOS return code, but i had already re-worked
  15.      my code.
  16.  
  17.      this is almost entirely CLIENT controlled. the server makes few
  18.      decisions. all filenames are translated at the client, etc...
  19. */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <dos.h>
  23. #include <dir.h>
  24. #include <string.h>
  25. #include <assert.h>
  26. #include <io.h>
  27. #include <fcntl.h>
  28. #include <sys\stat.h>
  29. #include <errno.h>
  30. #include <conio.h>
  31. #include <time.h>
  32.  
  33. #include "ifs.h"
  34. #include "comio.h"
  35. #include "crc32.h"
  36. #include "svr0.h"
  37. #include "myalloc.h"
  38. #include "rifs.h"
  39.  
  40. #include "rclient.h"
  41. #include "local.h"
  42. unsigned _stklen = 512;      /* minimal local stack */
  43.  
  44. BYTE    *SDA;           /* swappable data area         */
  45. WORD     SDA_maxsize;   /* size of SDA                 */
  46. WORD     SDA_minsize;   /* min. size of SDA            */
  47. BYTE    *SDA_DOSBUSY;   /* DOS busy flag               */
  48. BYTE    *CDS_base;      /* current directory structure */
  49. WORD     CDS_EntrySize; /* # of bytes per entry        */
  50. WORD     CDS_ct;        /* number of entries           */
  51. WORD     CDS_TotalSize; /* total number of bytes       */
  52.  
  53. /*************************************************************************
  54.  *************************************************************************
  55.   SERVER
  56.  *************************************************************************
  57.  *************************************************************************/
  58. XMITBUF *iobuf;    /* send / recieve buffer(s)    */
  59. XMITBUF *iobufptr; /* pointer to recieve buffer */
  60.  
  61. BYTE *lcl_SDA;  /* local copy of SDA    */
  62. CDS  *lcl_CDS;  /* local copy of CDS    */
  63.  
  64. LOCAL int   datasize = BLOCKSIZE; /* size of packet data  */
  65.  
  66. LOCAL int   state;    /*
  67.                           used by ASYNC for state info:
  68.                           0 = looking for 'K'
  69.                           1 = looking for 'Y'
  70.                           2 = storing ALL incoming
  71.                           3 = waiting to finish server request
  72.                        */
  73. LOCAL IFS_STAT IFS_stat; /* struct for keeping statistics */
  74.  
  75. BOOL background=TRUE; /* TRUE if running in background, else FALSE */
  76.  
  77. LOCAL unsigned openpsp[MAXOPEN];
  78.  
  79. #define SETRESULT(a) {iobufptr->length=0; iobufptr->cmd=a;}
  80.  
  81. /*
  82.   remove directory
  83.     ASCIIz = name of directory to remove
  84. */
  85. LOCAL void svr_rmdir(XMITBUF *iobuf)
  86. {
  87.   if (rmdir(iobuf->data)) {
  88.     SETRESULT(_doserrno);
  89.   } else
  90.     SETRESULT(0);
  91. }
  92.  
  93. /*
  94.   make directory
  95.     ASCIIz = name of directory to create
  96. */
  97. LOCAL void svr_mkdir(XMITBUF *iobuf)
  98. {
  99.   if (mkdir(iobuf->data)) {
  100.     SETRESULT(_doserrno);
  101.   } else
  102.     SETRESULT(0);
  103. }
  104. /*
  105.   change directory
  106.     ASCIIz = name of directory to change
  107. */
  108. LOCAL void svr_chdir(XMITBUF *iobuf)
  109. {
  110.   if (chdir(iobuf->data)) {
  111.     SETRESULT(_doserrno);
  112.   } else
  113.     SETRESULT(0);
  114. }
  115.  
  116. /*
  117.   close file
  118.     WORD : handle of file to close
  119. */
  120. LOCAL void svr_closefile(XMITBUF *iobuf)
  121. {
  122.   unsigned cascade_error;
  123.   int handle = *(unsigned *) iobuf->data;
  124.  
  125.   if (setftime(handle, (struct ftime *) (iobuf->data+2)))
  126.     cascade_error = _doserrno;
  127.   else
  128.     cascade_error = 0;
  129.  
  130.   if (close(handle)) {
  131.     SETRESULT(_doserrno);
  132.   } else
  133.     SETRESULT(cascade_error);
  134.  
  135.   if (handle < MAXOPEN)
  136.     openpsp[handle]=0;
  137. }
  138.  
  139. /*
  140.   commit file buffers
  141.     WORD : handle of file to commit
  142. */
  143. LOCAL void svr_commitfile(XMITBUF *iobuf)
  144. {
  145.   SETRESULT(0);
  146. }
  147.  
  148. /*
  149.   read from a file
  150.     WORD  : handle
  151.     DWORD : position
  152.     WORD  : length
  153.   returns
  154.     WORD   : number of bytes read
  155.     BYTE[] : bytes
  156. */
  157. LOCAL void svr_readfile(XMITBUF *iobuf)
  158. {
  159.   int  handle=*(int *) iobuf->data;
  160.   long pos=   *(long *) (iobuf->data+2);
  161.   int  len=   *(int *) (iobuf->data+6);
  162.   int  rlen;
  163.  
  164.   lseek(handle, pos, SEEK_SET);
  165.   errno = 0;
  166.   _doserrno = 0;
  167.   rlen = read(handle, iobuf->data+2, len);
  168.   if (rlen != len) {
  169.     SETRESULT(_doserrno);
  170.   } else
  171.     SETRESULT(0);
  172.   *(int *) iobuf->data=rlen;
  173.   iobuf->length=2+rlen;
  174. }
  175.  
  176. /*
  177.   write to file
  178.     WORD    : file handle
  179.     DWORD   : position
  180.     WORD    : length
  181.     BYTES[] : data
  182.   return
  183.     WORD    : bytes written, 0xffff = error
  184. */
  185. LOCAL void svr_writefile(XMITBUF *iobuf)
  186. {
  187.   int  handle=*(int *) iobuf->data;
  188.   long pos=   *(long *) (iobuf->data+2);
  189.   int  len=   *(int *) (iobuf->data+6);
  190.   int wlen;
  191.  
  192.   lseek(handle, pos, SEEK_SET);
  193.   errno    = 0;
  194.   _doserrno = 0;
  195.   wlen = write(handle, iobuf->data+8, len);
  196.   if (wlen != len) {
  197.     SETRESULT(_doserrno);
  198.   } else
  199.     SETRESULT(0);
  200.   *(int *) iobuf->data=wlen;
  201.   iobuf->length=2;
  202. }
  203.  
  204. /*
  205.   lock file bytes
  206.     WORD  : handle
  207.     DWORD : position
  208.     DWORD : length
  209. */
  210. LOCAL void svr_lockfile(XMITBUF *iobuf)
  211. {
  212.   int handle=*(int *) iobuf->data;
  213.   long pos = *(long *) (iobuf->data + 2);
  214.   long len = *(long *) (iobuf->data + 6);
  215.  
  216.   if (lock(handle, pos, len)) {
  217.     SETRESULT(_doserrno);
  218.   } else
  219.     SETRESULT(0);
  220. }
  221.  
  222. /*
  223.   lock/unlock file bytes
  224.     WORD  : handle
  225.     WORD  : function (0 = lock / 1 = unlock)
  226.     DWORD : position
  227.     DWORD : size
  228. */
  229. LOCAL void svr_unlockfile(XMITBUF *iobuf)
  230. {
  231.   int handle=*(int *)   iobuf->data;
  232.   int fn    =*(int *)  (iobuf->data + 2);
  233.   long pos = *(long *) (iobuf->data + 4);
  234.   long len = *(long *) (iobuf->data + 8);
  235.   int  result;
  236.  
  237.   result = (fn) ? lock(handle, pos, len) : unlock(handle, pos, len);
  238.   if (result) {
  239.     SETRESULT(_doserrno);
  240.   } else
  241.     SETRESULT(0);
  242. }
  243.  
  244. /*
  245.   get free space
  246.     BYTE : drive number (0 = a)
  247.   return
  248.     struct dfree
  249. */
  250. LOCAL void svr_getspace(XMITBUF *iobuf)
  251. {
  252.   struct dfree *df=(void *) iobuf->data;
  253.   getdfree(iobuf->data[0], df);
  254.   if (df->df_sclus == 0xffff) {
  255.     SETRESULT(_doserrno);
  256.   } else {
  257.     SETRESULT(0);
  258.   }
  259.   iobuf->length = sizeof(*df);
  260. }
  261.  
  262. /*
  263.   set file attribute
  264.     WORD   : attribute
  265.     ASCIIz : filename
  266. */
  267. LOCAL void svr_setattr(XMITBUF *iobuf)
  268. {
  269.   if (chmod(iobuf->data+2, *(int *) iobuf->data)) {
  270.     SETRESULT(_doserrno);
  271.   } else
  272.     SETRESULT(0);
  273. }
  274.  
  275. /*
  276.   return file attribute
  277.     ASCIIz : filename
  278.   return
  279.     WORD   : attribute
  280. */
  281. LOCAL void svr_getattr(XMITBUF *iobuf)
  282. {
  283.   struct REGPACK regs;
  284.  
  285.   regs.r_ax=0x4300;
  286.   regs.r_dx=FP_OFF(iobuf->data);
  287.   regs.r_ds=FP_SEG(iobuf->data);
  288.   intr(0x21, ®s);
  289.   if (regs.r_flags & 0x01) {
  290.     SETRESULT(regs.r_ax);
  291.   } else {
  292.     SETRESULT(0);
  293.     *(int *) iobuf->data=regs.r_cx;
  294.     iobuf->length=2;
  295.   }
  296. }
  297.  
  298. /*
  299.   rename file
  300.     ASCIIz : old name
  301.     ASCIIz : new name
  302. */
  303. LOCAL void svr_renamefile(XMITBUF *iobuf)
  304. {
  305.   if (rename(iobuf->data, iobuf->data+strlen(iobuf->data)+1)) {
  306.     SETRESULT(_doserrno);
  307.   } else
  308.     SETRESULT(0);
  309. }
  310.  
  311. /*
  312.   delete file
  313.     ASCIIz : filename
  314. */
  315. LOCAL void svr_deletefile(XMITBUF *iobuf)
  316. {
  317.   if (unlink(iobuf->data)) {
  318.     SETRESULT(_doserrno);
  319.   } else
  320.     SETRESULT(0);
  321. }
  322.  
  323. /*
  324.   open file
  325.     WORD   : open mode
  326.     ASCIIz : filename
  327.   return
  328.     WORD   : file handle
  329.     WORD   : file attribute
  330.     WORD   : file time
  331.     WORD   : file date
  332.     DWORD  : file length
  333. */
  334. LOCAL void svr_openfile(XMITBUF *iobuf)
  335. {
  336.   struct REGPACK regs;
  337.   /*
  338.     call DOS open
  339.   */
  340.   regs.r_ax=0x3d00 | ((*(int *) iobuf->data) & 0xff);
  341.   regs.r_dx=FP_OFF(iobuf->data)+2;
  342.   regs.r_ds=FP_SEG(iobuf->data);
  343.   intr(0x21, ®s);
  344.   if (regs.r_flags & 0x01) {
  345.     SETRESULT(regs.r_ax);
  346.   } else {
  347.     SETRESULT(0);
  348.     if (regs.r_ax < MAXOPEN)
  349.       openpsp[regs.r_ax]=iobuf->process_id;
  350.     *(int *) iobuf->data=regs.r_ax;
  351.     *(int *) (iobuf->data+2)=_chmod(iobuf->data+2, 0);
  352.     regs.r_bx=*(int *) iobuf->data